#include "ctrl.h"
#include "data_center/data_center.h"
#include "pico/stdlib.h"
#include "srt/srt.h"

#define LOG_TAG "CTRL"
#include "log/log.h"

// static Bool is_init_ = False;
// static Bool is_blink_ = False;
// static UInt32 last_ctrl_tick_ = 0;

#define ACC_SWITCH_PIN 14  ///< ACC开关量控制脚
#define PWR_SWITCH_PIN 11  ///< PWR开关量控制脚

/**
 * TCtrl 控制结构体
 */
struct TCtrlTag
{
    Bool is_init_;  ///<
    Bool is_blink_;  ///<
    UInt32 last_ctrl_tick_;
};
typedef struct TCtrlTag TCtrl;

static TCtrl obj_ = {
    .is_init_        = False,
    .is_blink_       = False,
    .last_ctrl_tick_ = 0,
};
static TCtrl* self = &obj_;

Bool TCtrlInit()
{
    TDataCenterInit(kDataCenterUserCtrl);

    gpio_init(PICO_DEFAULT_LED_PIN);
    gpio_init(ACC_SWITCH_PIN);
    gpio_init(PWR_SWITCH_PIN);

    gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT);
    gpio_set_dir(ACC_SWITCH_PIN, GPIO_OUT);
    gpio_set_dir(PWR_SWITCH_PIN, GPIO_OUT);

    gpio_put(ACC_SWITCH_PIN, True);
    TSrtSetBool(kSrtBoolAccStatus, True);
    gpio_put(PWR_SWITCH_PIN, True);
    TSrtSetBool(kSrtBoolPwrStatus, True);

    self->is_init_ = True;
}

Bool TCtrlFini()
{
    self->is_init_ = False;
    TDataCenterFini(kDataCenterUserCtrl);
}

static void DealMsg(TDataCenterMsg *msg)
{
    if (msg != NULL)
    {
        Bool is_update_screen = True;

        LOG_D("Get Data Center msg! msg type: %d", msg->msg_type);

        switch (msg->msg_type)
        {
        case kDataCenterMsgTypeCmdOpenAcc:  ///< shell->ctrl 打开ACC
        {
            gpio_put(ACC_SWITCH_PIN, True);
            TSrtSetBool(kSrtBoolAccStatus, True);
            LOG_D("Open acc succ");

            break;
        }
        case kDataCenterMsgTypeCmdCloseAcc:  ///< shell->ctrl 关闭ACC
        {
            gpio_put(ACC_SWITCH_PIN, False);
            TSrtSetBool(kSrtBoolAccStatus, False);
            LOG_D("Close acc succ");

            break;
        }
        case kDataCenterMsgTypeCmdOpenPwr:  ///< shell->ctrl 打开PWR
        {
            gpio_put(PWR_SWITCH_PIN, True);
            TSrtSetBool(kSrtBoolPwrStatus, True);
            LOG_D("Open pwr succ");

            break;
        }
        case kDataCenterMsgTypeCmdClosePwr:  ///< shell->ctrl 关闭PWR
        {
            gpio_put(PWR_SWITCH_PIN, False);
            TSrtSetBool(kSrtBoolPwrStatus, False);
            LOG_D("Close pwr succ");

            break;
        }

        default:
            LOG_W("Unknown msg type, ignore msg.");
            is_update_screen = False;
            break;
        }

        if (is_update_screen)
        {
            TDataCenterMsg *msg = TDataCenterCreateMsg(0);

            if (msg != NULL)
            {
                msg->receiver = kDataCenterUserScreen;
                msg->msg_type = kDataCenterMsgTypeUpdateScreen;
                msg->content_len = 0;

                TDataCenterSendMsg(kDataCenterUserCtrl, msg);
            }
        }
    }
}

void TCtrlRunOnce(UInt32 cur_ticks)
{
    if (self->is_init_)
    {
        // 控灯
        if (cur_ticks - self->last_ctrl_tick_ >= 1000)
        {
            if (self->is_blink_)
            {
                gpio_put(PICO_DEFAULT_LED_PIN, 0);
                self->is_blink_ = False;
            }
            else
            {
                gpio_put(PICO_DEFAULT_LED_PIN, 1);
                self->is_blink_ = True;
            }

            self->last_ctrl_tick_ = cur_ticks;
        }

        // 消息交互
        TDataCenterMsg *msg = TDataCenterPopMsg(kDataCenterUserCtrl);

        if (msg != NULL)
        {
            DealMsg(msg);
            TDataCenterDestroyMsg(msg);
        }
    }
}
